/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package tarea1automatas;
import java.util.ArrayList;
/**
 *
 * @author MarioEspinoza
 */
public class AFD extends AutomataFinito {
    //private ArrayList<Integer[][]> matricesAdyacencia = new ArrayList<Integer[][]>();
    int cantidadEstados;
    int cantidadSimbolos;

    public AFD()
    {
                
    }

    public AFD(AutomataFinito af)
    {
        this.estados=af.estados;
        this.simbolosLenguaje=af.simbolosLenguaje;
        this.cantidadEstados = estados.size();
        this.cantidadSimbolos = simbolosLenguaje.size();

    }

    public void reconocerAFD ( ArrayList <String>lineasArchivo)
    {
        for (int v=4;v<lineasArchivo.size();v++)
         {
                             System.out.println(lineasArchivo.get(v));
          }
    }
    public AFD afdMinimo()
    {
        AFD porMinimizar = this;
        AFD minimo = null;
        
        ArrayList<Estado> finales = new ArrayList<Estado>();
        ArrayList<Estado> noFinales = new ArrayList<Estado>();
        for(int i = 0;i<this.estados.size();i++)
        {
            Estado temporal = this.estados.get(i);
            if(temporal.isEstadoFinal())
                finales.add(temporal);
            else
                noFinales.add(temporal);
        }

        ArrayList<ArrayList<Estado>> estadosAFD = new ArrayList<ArrayList<Estado>>();

        estadosAFD.add(noFinales);
        estadosAFD.add(finales);


        ArrayList<ArrayList<Estado>> resultado = porMinimizar.minimizar(estadosAFD,this.estados.size());
        if (estadosAFD.equals(resultado))
        {
            System.out.println("Este AFD es Minimo");
            minimo=porMinimizar;
        }
        else
        {
            minimo = new AFD();
            minimo.simbolosLenguaje = this.simbolosLenguaje;

            for(int i =0;i<resultado.size();i++)
            {
                Estado nuevo =new Estado();
                nuevo.setNombre(i);
                nuevo.setMatricesAdyacencia(resultado.get(i).get(0).getMatricesAdyacencia());
                minimo.estados.add(nuevo);
            }
        }
        return minimo;
    }

    private ArrayList<ArrayList<Estado>> minimizar(ArrayList<ArrayList<Estado>> listaGruposEstados,int cantidadEstados)
    {
        //@todo definir mejor algoritmo
        //while()
        ArrayList<ArrayList<Estado>> listaGruposEstadosResultante = new ArrayList<ArrayList<Estado>>();
        int cantidadGrupos = listaGruposEstados.size();
        for(int i = 0;i<cantidadGrupos;i++)
        {
            ArrayList<Estado> listaEstados = new ArrayList<Estado>();

            for(int j = 0;j<cantidadGrupos-1;j++)
            {
                //tomo un estado
                Estado a = listaEstados.get(j);
                listaEstados.add(a);
                for(int k = j+1;k<cantidadGrupos;k++)
                {                    
                    Estado b = listaEstados.get(k);

                    if(a.getMatricesAdyacencia().equals(b.getMatricesAdyacencia()))
                    {
                        listaEstados.add(b);
                    }
                    else
                    {
                        if(listaEstados.size()>1)
                            listaGruposEstadosResultante.add(listaEstados);

                        ArrayList<Estado> nuevaLista = new ArrayList<Estado>();
                        nuevaLista.add(b);
                    }
                }
            }       
        }
        return listaGruposEstadosResultante;
    }

    private boolean ExtraerMatricesAdyacencia()
    {
        boolean resultado = true;
        for(int l = 0;l<this.cantidadEstados-1;l++)
        {
            Estado eA = estados.get(l);
            Estado eB = estados.get(l+1);

            for(int k = 0;k<cantidadSimbolos;k++)
            {
               boolean[][] matrizA = eA.getMatricesAdyacencia().get(k);
               boolean[][] matrizB = eB.getMatricesAdyacencia().get(k);

               if(matrizA == matrizB)
                   resultado = resultado && true;
               else
                   return false;

            }
        }
        return resultado;
    }

    /*
    private ArrayList<Estado> clausuraVacia(Estado e)
    {
        //@todo definir Clausura Vacia
        ArrayList<Estado> resultante = new ArrayList<Estado>();

        ArrayList<String> transicionesEstado = e.getTransiciones();
        int cantidadTransiciones = transicionesEstado.size();

        resultante.add(e);

        for(int i = 0;i<cantidadTransiciones;i++ )
        {
            if(transicionesEstado.get(i).equals("e"))
                resultante.add(this.getEstadoPorNombre(e.getDestinoTransicion().get(i)));
        }

        return resultante;
    }*/

}
